using Microsoft.EntityFrameworkCore;
using Order.Api.Read.Application.Command;
using Order.Api.Read.Dto.Order;
using Order.Api.Read.Service.PrescriptionOrderService;
using Order.ErrorCode;
using Order.Domain.OrderDomain;
using Order.Domain.Enum;
using Order.Interstructrue;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Order.Api.Read.Service.PrescriptionOrderService
{
    /// <summary>
    /// 处方订单服务实现
    /// </summary>
    public class PrescriptionOrderService : IPrescriptionOrderService
    {
        private readonly MedicalDbContext _context;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">数据库上下文</param>
        public PrescriptionOrderService(MedicalDbContext context)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context), "数据库上下文不能为空");
        }

        /// <summary>
        /// 获取处方订单分页数据
        /// 支持关键字搜索、时间范围筛选、处方订单状态筛选
        /// </summary>
        /// <param name="command">分页查询命令</param>
        /// <returns>分页结果</returns>
        /// <exception cref="ArgumentNullException">当command为null时抛出</exception>
        public async Task<ApiPageIng<PrescriptionOrderPageDto>> GetPrescriptionOrderPageAsync(PrescriptionOrderPageCommand command)
        {
            try
            {
                // 参数验证
                if (command == null)
                {
                    throw new ArgumentNullException(nameof(command), "分页查询命令不能为空");
                }

                if (command.Query == null)
                {
                    command.Query = new PrescriptionOrderQueryDto();
                }

                // 参数验证和默认值设置
                if (command.Query.PageIndex <= 0)
                {
                    command.Query.PageIndex = 1;
                }

                if (command.Query.PageSize <= 0)
                {
                    command.Query.PageSize = 10;
                }

                // 构建查询
                var query = from po in _context.PrescriptionOrder
                            join p in _context.Patient on po.PatientId equals p.Id into patientJoin
                            from p in patientJoin.DefaultIfEmpty()
                            join pr in _context.Prescription on po.Id equals pr.PrescriptionOrderId into prescriptionJoin
                            from pr in prescriptionJoin.DefaultIfEmpty()
                            where !po.IsDeleted
                            select new PrescriptionOrderPageDto
                            {
                                Id = po.Id,
                                OrderNo = po.OrderNo,
                                PrescriptionNo = pr.PrescriptionNo,
                                PatientName = p.PatientName,
                                Department = pr.Department,
                                Doctor = pr.Doctor,
                                Cost = po.Cost,
                                OrderStatus = po.OrderStatus,
                                PrescriptionStatus = pr.PrescriptionStatus,
                                PurchaseMethod = po.PurchaseMethod,
                                DispensingStatus = po.DispensingStatus,
                                CreateTime = po.CreateTime
                            };

                // 应用查询条件
                query = ApplyQueryConditions(query, command.Query);

                // 排序
                query = query.OrderByDescending(x => x.CreateTime);

                // 获取总数
                var totalCount = await query.CountAsync();

                // 分页
                var pageData = await query
                    .Skip((command.Query.PageIndex - 1) * command.Query.PageSize)
                    .Take(command.Query.PageSize)
                    .ToListAsync();

                // 设置枚举名称
                foreach (var item in pageData)
                {
                    item.OrderStatusName = GetEnumName(item.OrderStatus);
                    item.PrescriptionStatusName = GetEnumName(item.PrescriptionStatus);
                    item.PurchaseMethodName = GetEnumName(item.PurchaseMethod);
                    item.DispensingStatusName = GetEnumName(item.DispensingStatus);
                    item.DepartmentName = GetDepartmentName(item.Department);
                }

                // 构建分页结果
                var result = new ApiPageIng<PrescriptionOrderPageDto>
                {
                    PageIndex = command.Query.PageIndex,
                    PageSize = command.Query.PageSize,
                    TotalCount = totalCount,
                    TotalPages = (int)Math.Ceiling((double)totalCount / command.Query.PageSize),
                    Data = pageData
                };

                return result;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                // TODO: 添加日志记录
                throw new Exception($"获取处方订单分页数据时发生错误: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 应用查询条件
        /// </summary>
        /// <param name="query">查询对象</param>
        /// <param name="queryDto">查询条件</param>
        /// <returns>应用条件后的查询对象</returns>
        private IQueryable<PrescriptionOrderPageDto> ApplyQueryConditions(IQueryable<PrescriptionOrderPageDto> query, PrescriptionOrderQueryDto queryDto)
        {
            // 关键字搜索（患者姓名、手机号）
            if (!string.IsNullOrWhiteSpace(queryDto.Keyword))
            {
                // 需要重新构建查询以包含患者手机号
                var baseQuery = from po in _context.PrescriptionOrder
                                join p in _context.Patient on po.PatientId equals p.Id into patientJoin
                                from p in patientJoin.DefaultIfEmpty()
                                join pr in _context.Prescription on po.Id equals pr.PrescriptionOrderId into prescriptionJoin
                                from pr in prescriptionJoin.DefaultIfEmpty()
                                where !po.IsDeleted
                                select new
                                {
                                    po,
                                    p,
                                    pr
                                };

                // 应用关键字搜索
                baseQuery = baseQuery.Where(x =>
                    (x.p.PatientName != null && x.p.PatientName.Contains(queryDto.Keyword)) ||
                    (x.p.Phone != null && x.p.Phone.Contains(queryDto.Keyword))
                );

                // 重新构建DTO查询
                query = baseQuery.Select(x => new PrescriptionOrderPageDto
                {
                    Id = x.po.Id,
                    OrderNo = x.po.OrderNo,
                    PrescriptionNo = x.pr.PrescriptionNo,
                    PatientName = x.p.PatientName,
                    Department = x.pr.Department,
                    Doctor = x.pr.Doctor,
                    Cost = x.po.Cost,
                    OrderStatus = x.po.OrderStatus,
                    PrescriptionStatus = x.pr.PrescriptionStatus,
                    PurchaseMethod = x.po.PurchaseMethod,
                    DispensingStatus = x.po.DispensingStatus,
                    CreateTime = x.po.CreateTime
                });
            }

            // 时间范围筛选（查询创建时间）
            if (queryDto.StartTime.HasValue)
            {
                query = query.Where(x => x.CreateTime >= queryDto.StartTime.Value);
            }

            if (queryDto.EndTime.HasValue)
            {
                query = query.Where(x => x.CreateTime <= queryDto.EndTime.Value);
            }

            // 处方订单状态筛选
            if (queryDto.OrderStatus.HasValue)
            {
                query = query.Where(x => x.OrderStatus == queryDto.OrderStatus.Value);
            }

            return query;
        }

        /// <summary>
        /// 获取枚举名称
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="enumValue">枚举值</param>
        /// <returns>枚举名称</returns>
        private string? GetEnumName<T>(T? enumValue) where T : struct, Enum
        {
            try
            {
                if (!enumValue.HasValue)
                    return null;
                return enumValue.Value.ToString();
            }
            catch (Exception ex)
            {
                // TODO: 添加日志记录
                return enumValue?.ToString();
            }
        }

        /// <summary>
        /// 获取科室名称
        /// </summary>
        /// <param name="department">科室枚举</param>
        /// <returns>科室名称</returns>
        private string? GetDepartmentName(Order.Domain.Enum.DeptEnum? department)
        {
            if (!department.HasValue)
                return null;

            return department.Value switch
            {
                Order.Domain.Enum.DeptEnum.内科 => "内科",
                Order.Domain.Enum.DeptEnum.外科 => "外科",
                _ => department.Value.ToString()
            };
        }

        /// <summary>
        /// 获取处方订单详情
        /// 包含患者信息、处方信息、药品信息
        /// </summary>
        /// <param name="command">详情查询命令</param>
        /// <returns>处方订单详情</returns>
        public async Task<PrescriptionOrderDetailDto> GetPrescriptionOrderDetailAsync(PrescriptionOrderDetailCommand command)
        {
            try
            {
                // 参数验证
                if (command == null)
                {
                    throw new ArgumentNullException(nameof(command), "详情查询命令不能为空");
                }

                if (command.Id <= 0)
                {
                    throw new ArgumentException("处方订单ID必须大于0", nameof(command.Id));
                }

                // 查询处方订单基本信息
                var prescriptionOrder = await _context.PrescriptionOrder
                    .FirstOrDefaultAsync(x => x.Id == command.Id && !x.IsDeleted);

                if (prescriptionOrder == null)
                {
                    throw new InvalidOperationException($"未找到ID为{command.Id}的处方订单");
                }

                // 查询患者信息
                var patient = await _context.Patient
                    .FirstOrDefaultAsync(x => x.Id == prescriptionOrder.PatientId && !x.IsDeleted);

                // 查询处方信息
                var prescription = await _context.Prescription
                    .FirstOrDefaultAsync(x => x.PrescriptionOrderId == command.Id && !x.IsDeleted);

                // 查询药品信息（这里假设有药品表，如果没有需要根据实际情况调整）
                var drugs = await _context.Drug
                    .Where(x => x.DrugOrderId == command.Id && !x.IsDeleted)
                    .ToListAsync();

                // 构建详情DTO
                var detailDto = new PrescriptionOrderDetailDto
                {
                    Id = prescriptionOrder.Id,
                    OrderNo = prescriptionOrder.OrderNo,
                    OrderStatus = prescriptionOrder.OrderStatus,
                    OrderStatusName = GetEnumName(prescriptionOrder.OrderStatus),
                    PurchaseMethod = prescriptionOrder.PurchaseMethod,
                    PurchaseMethodName = GetEnumName(prescriptionOrder.PurchaseMethod),
                    Cost = prescriptionOrder.Cost,
                    // 这里可以根据实际业务逻辑计算优惠券和实际支付金额
                    CouponAmount = 10, // 示例值
                    ActualPayment = prescriptionOrder.Cost - 10, // 示例计算
                    PaymentMethod = "微信", // 示例值
                    PaymentTime = prescriptionOrder.CreateTime, // 示例值
                    CreateTime = prescriptionOrder.CreateTime,
                    PatientInfo = patient != null ? new PatientInfoDto
                    {
                        PatientName = patient.PatientName,
                        Sex = patient.Sex,
                        Age = patient.Age,
                        Phone = patient.Phone,
                        Address = patient.Address,
                        Disease = patient.Disease,
                        LiverFunction = patient.LiverFunction,
                        KidneyFunction = patient.KidneyFunction,
                        AllergyHistory = patient.AllergyHistory,
                        ReproductiveStatus = patient.ReproductiveStatus,
                        DiseaseDescription = patient.DiseaseDescription
                    } : null,
                    PrescriptionInfo = prescription != null ? new PrescriptionInfoDto
                    {
                        PrescriptionNo = prescription.PrescriptionNo,
                        CreateTime = prescription.CreateTime,
                        PrescriptionStatus = prescription.PrescriptionStatus,
                        PrescriptionStatusName = GetEnumName(prescription.PrescriptionStatus),
                        DispensingStatus = prescriptionOrder.DispensingStatus,
                        DispensingStatusName = GetEnumName(prescriptionOrder.DispensingStatus),
                        Doctor = prescription.Doctor,
                        Department = prescription.Department,
                        DepartmentName = GetDepartmentName(prescription.Department),
                        PrimaryDiagnosis = prescription.PrimaryDiagnosis,
                        Advice = prescription.Advice,
                        Drugs = drugs.Select(x => new PrescriptionDrugDto
                        {
                            DrugName = x.DrugName,
                            Quantity = x.Num,
                            Specification = x.Specif,
                            Dosage = x.Dosage,
                            UnitPrice = x.UnitPrice,
                            SubTotal = (x.UnitPrice ?? 0) * (x.Num ?? 0)
                        }).ToList()
                    } : null
                };

                return detailDto;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                // TODO: 添加日志记录
                throw new Exception($"获取处方订单详情时发生错误: {ex.Message}", ex);
            }
        }
    }
}